package com.demo.mycamera;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class Camera1Activity extends Activity implements SurfaceHolder.Callback {
    private Camera mCamera;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder ;

    private static final int REQUEST_TAKEPHOTO_CODE2 = 0x00000010;
    private final static int CAMERA_OK = 10001;
    private static final int REQUEST_IMAGE = 1;
    public static int width = 1920;
    public static int height = 1080;
    private static String[] PERMISSIONS_STORAGE = {
            "android.permission.CAMERA",
            "android.permission.WRITE_EXTERNAL_STORAGE" };

    private String TAG = "Camera1";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera1);
        mSurfaceView = findViewById(R.id.preview);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        // 先申请权限
        if (Build.VERSION.SDK_INT > 22 && !checkPermissionAllGranted(PERMISSIONS_STORAGE)) {
            ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, CAMERA_OK);
        }
    }

    private boolean checkPermissionAllGranted(String[] permissions) {
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                // 只要有一个权限没有被授予, 则直接返回 false
                return false;
            }
        }
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();

        if(mSurfaceHolder != null){
            startCameraPreview(mCamera,mSurfaceHolder);
        }
    }

    @Override
    protected void onPause() {
        Log.d(TAG,"onPause()");
        super.onPause();
        realseCamera();
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG,"onDestroy()");
        super.onDestroy();
        realseCamera();
    }

    public Camera getCamera(){
        //有多少个摄像头
        int numberOfCameras = Camera.getNumberOfCameras();
        int faceFrontCameraId = 0;
        int faceFrontCameraOrientation = 0;
        int faceBackCameraId = 0;
        int faceBackCameraOrientation = 0;

        for (int i = 0; i < numberOfCameras; ++i) {
            final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();

            Camera.getCameraInfo(i, cameraInfo);
            //后置摄像头
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                Log.d(TAG,"Camera facing back");
                faceBackCameraId = i;
                faceBackCameraOrientation = cameraInfo.orientation;
            }
            //前置摄像头
            else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                Log.d(TAG,"Camera facing front");
                faceFrontCameraId = i;
                faceFrontCameraOrientation = cameraInfo.orientation;
            }
        }

        Log.d(TAG,"camera orientation:" + faceFrontCameraOrientation);
        if(mCamera == null){
            mCamera =Camera.open(0);
        }
        return mCamera;
    }

    /**
     * 开始预览相机内容
     */
    public void startCameraPreview(Camera camera,SurfaceHolder holder){
        if(camera != null){
            try {
                Camera.Parameters parameters = camera.getParameters();
                parameters.setPreviewFormat(ImageFormat.NV21); // 预览格式
                //设置预览大小
                parameters.setPreviewSize(1280, 720);
                parameters.setPreviewFrameRate(5);//一秒25帧
                // 输出摄像头支持的尺寸
                int lastWidth = 0;
                int lastHeight = 0;
                boolean foundMatchSize = false;
                List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
                for (Camera.Size size : sizeList) {
                    Log.d(TAG, "startCamera supportedPreviewSize: width=" + size.width + ", height=" + size.height);
                    lastWidth = size.width;
                    lastHeight = size.height;
                    if (size.width == width && size.height == height) {
                        foundMatchSize = true;
                    }
                }
                Log.d(TAG,String.valueOf(camera.getParameters().getPreviewFormat()) + " :format :" + String.valueOf(ImageFormat.NV21));
                Log.d(TAG,"width:" + String.valueOf(camera.getParameters().getPreviewSize().width) + ",height:" + String.valueOf(camera.getParameters().getPreviewSize().height));
                //设置相机参数
                camera.setParameters(parameters);
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (IOException e) {
                Log.d(TAG,e.toString());
            }
        }
    }

    /**
     * 释放相机资源
     */
    public void realseCamera(){
        if(mCamera != null){
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG,"surfaceCreated");
        getCamera();
        if(mCamera != null){
            startCameraPreview(mCamera,mSurfaceHolder);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.d(TAG,"surfaceChanged");
        if (holder.getSurface() == null) {
            return;
        }
        //停止预览效果
        mCamera.stopPreview();
        //重新设置预览效果
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            Log.d(TAG,e.toString());
        }
        mCamera.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(TAG,"surfaceDestroyed");
        realseCamera();
    }

    String mImagePathName;

    public void startCapture(View view) {
        //得到照相机的参数
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureSize(1280,720);
        mCamera.setParameters(parameters);
        mCamera.takePicture(null, null,new MyPictureCallback());
    }

    //拍照后回调
    private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            String mPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath()+"/"+ System.currentTimeMillis() + "_temp520.png";
            Log.d(TAG,"save pic to:" + mPath);
            File file = new File(mPath);
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(file);
                fileOutputStream.write(data);

            } catch (FileNotFoundException e) {
                Log.d(TAG,e.toString());
            } catch (IOException e) {
                Log.d(TAG,e.toString());
            }finally {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    Log.d(TAG,e.toString());
                }
            }
            mCamera.stopPreview();
            mCamera.startPreview();
        }

    };

    private final class MyPictureCallback implements Camera.PictureCallback {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // 保存图片操作
            Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
            String fileName=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString()
                    + File.separator
                    + System.currentTimeMillis() + "_temp520.png";
            Log.d(TAG,"save pic to:" + fileName);
            File file=new File(fileName);
            if(!file.getParentFile().exists()){
                file.getParentFile().mkdir();//创建文件夹
            }
            try {
                BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file));
                bmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);//向缓冲区压缩图片
                bos.flush();
                bos.close();
                Toast.makeText(getApplicationContext(), "拍照成功，照片保存在"+fileName+"文件之中！", Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Log.d(TAG,e.toString());
                Toast.makeText(getApplicationContext(), "拍照失败！", Toast.LENGTH_LONG).show();
            }
            mCamera.stopPreview();
            mCamera.startPreview();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1) {
            FileInputStream mFis = null;
            try {
                mFis = new FileInputStream(mImagePathName);
                Bitmap bitmap = BitmapFactory.decodeStream(mFis);
                Log.d(TAG,"width--->" + bitmap.getWidth() + "\n" + "height--->" + bitmap.getHeight() + "\n" + "byte--->" + bitmap.getByteCount() / 1024);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (mFis != null) {
                        mFis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
